package com.archive.core.executor;

import com.archive.core.statistics.ArchiveStatistics;
import com.archive.core.table.ArchiveTable;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public interface ArchiveExecutor {

    /**
     * 检查并生成归档表
     *
     * @param tableName        原表名
     * @param archiveTableName 归档表名
     * @param connection       原表所在库连接
     * @param targetConnection 归档库连接（同库归档时为空）
     * @throws SQLException
     */
    void checkArchiveTable(String tableName, String archiveTableName, Connection connection,
                           Connection targetConnection) throws SQLException;

    /**
     * 查询原表数据
     *
     * @param archiveTable     原表信息
     * @param startTime        归档开始时间
     * @param archiveTimeStamp 归档时间点
     * @param maxPrimaryValue  当前最大主键值
     * @param connection       原表所在库连接
     * @return 当前最大主键值
     * @throws SQLException sql异常
     */
    Object queryData(ArchiveTable archiveTable, long startTime, Long archiveTimeStamp,
                     Object maxPrimaryValue, Connection connection) throws SQLException;

    /**
     * 获取查询数据sql
     *
     * @param archiveTable     原表信息
     * @param archiveTimeStamp 归档时间点
     * @param maxPrimaryValue  当前最大主键值
     * @return 查询数据的完整sql
     */
    String getQuerySql(ArchiveTable archiveTable, Long archiveTimeStamp, Object maxPrimaryValue);

    /**
     * 提取字段，用于关联表数据查询
     *
     * @param archiveTable    原表信息
     * @param maxPrimaryValue 当前最大主键值
     * @param resultSet       查询结果
     * @param extractColumns  要提取数据的列
     * @param extractDataMap  提取数据结果集
     * @param data            结果集
     * @return 当前数据的最大主键
     * @throws SQLException sql异常
     */
    Object extractQueryData(ArchiveTable archiveTable, Object maxPrimaryValue, ResultSet resultSet,
                            List<String> extractColumns, Map<String, List<Object>> extractDataMap, List<Object[]> data) throws SQLException;

    /**
     * 使用一般语法进行归档
     *
     * @param archiveTable      原表信息
     * @param targetTableName   归档表表名
     * @param connection        原表所在数据库连接
     * @param targetConnection  归档表目标库连接（同库归档时为空）
     * @param archiveStatistics 归档统计信息
     * @throws SQLException sql异常
     */
    void doArchiveNormal(ArchiveTable archiveTable, String targetTableName, Connection connection,
                         Connection targetConnection, ArchiveStatistics archiveStatistics) throws SQLException;

    /**
     * 使用预编译语法进行归档
     *
     * @param archiveTable      原表信息
     * @param archiveTableName  归档表表名
     * @param connection        原表所在数据库连接
     * @param targetConnection  归档表目标库连接（同库归档时为空）
     * @param archiveStatistics 归档统计信息
     * @throws SQLException sql异常
     */
    void doArchivePrepared(ArchiveTable archiveTable, String archiveTableName, Connection connection,
                           Connection targetConnection, ArchiveStatistics archiveStatistics) throws SQLException;

    /**
     * 主键冲突异常处理
     *
     * @param archiveTable      原表信息
     * @param targetTableName   归档表表表名
     * @param connection        原表所在数据库连接
     * @param targetConnection  归档表目标库连接（同库归档时为空）
     * @param archiveStatistics 归档统计信息
     * @throws SQLException sql异常
     */
    void handleDuplicateKeyException(ArchiveTable archiveTable, String targetTableName, Connection connection,
                                     Connection targetConnection, ArchiveStatistics archiveStatistics) throws SQLException;

    /**
     * 原生连接获取器
     *
     * @param originConnectionProvider 原生连接获取器
     */
    void setOriginConnectionProvider(OriginConnectionProvider originConnectionProvider);
}
